{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(12)\n",
    "x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([12])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.shape\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.numel()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = x.reshape(3, 4)\n",
    "x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0,  1,  2,  3],\n",
      "        [ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = x.reshape(-1, 4)\n",
    "print(x)\n",
    "x = x.reshape(3, -1)\n",
    "x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.]],\n",
       "\n",
       "        [[0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.]]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.zeros((2, 3, 4))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.ones((2, 3, 4))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.2213, -0.1686,  2.8447,  0.8886],\n",
       "        [-1.0939, -1.6082, -1.5612, -0.4489],\n",
       "        [ 0.5272,  0.5088,  0.0390,  0.7183]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.randn(3, 4)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1, 2, 3],\n",
       "        [4, 5, 6],\n",
       "        [7, 8, 9]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([3., 4., 5., 6.]),\n",
       " tensor([-1.,  0.,  1.,  2.]),\n",
       " tensor([2., 4., 6., 8.]),\n",
       " tensor([0.5000, 1.0000, 1.5000, 2.0000]),\n",
       " tensor([ 1.,  4.,  9., 16.]))"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.tensor([1.0, 2, 3, 4])\n",
    "y = torch.tensor([2, 2, 2, 2])\n",
    "# **运算符是求幂运算\n",
    "x+y, x-y, x*y, x/y, x**y\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 2.7183,  7.3891, 20.0855, 54.5981])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# E的n次方\n",
    "x = torch.tensor([1, 2, 3, 4])\n",
    "torch.exp(x)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0.],\n",
       "         [2., 1., 4., 3.],\n",
       "         [1., 2., 3., 4.],\n",
       "         [4., 3., 2., 1.]]),\n",
       " tensor([[0., 0., 0., 0., 2., 1., 4., 3.],\n",
       "         [0., 0., 0., 0., 1., 2., 3., 4.],\n",
       "         [0., 0., 0., 0., 4., 3., 2., 1.]]))"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.zeros(12, dtype=torch.float32).reshape((3, 4))\n",
    "y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])\n",
    "# 沿行（轴-0，形状的第一个元素） 和按列（轴-1，形状的第二个元素）连结两个矩阵\n",
    "torch.cat((x, y), dim=0), torch.cat((x, y), dim=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[False, False, False, False],\n",
       "        [False, False, False, False],\n",
       "        [False, False, False, False]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对于每个位置，如果X和Y在该位置相等，则新张量中相应项的值为1。 这意味着逻辑语句X == Y在该位置处为真，否则该位置为0\n",
    "x == y\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0, 1, 2, 3, 4])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor(10)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(5)\n",
    "print(x)\n",
    "# 对张量中的所有元素进行求和，会产生一个单元素张量\n",
    "x.sum()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0],\n",
      "        [1],\n",
      "        [2]])\n",
      "tensor([[0, 1]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[0, 1],\n",
       "        [1, 2],\n",
       "        [2, 3]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在某些情况下，即使形状不同，我们仍然可以通过调用 广播机制（broadcasting mechanism）来执行按元素操作。\n",
    "# 这种机制的工作方式如下：首先，通过适当复制元素来扩展一个或两个数组， 以便在转换之后，两个张量具有相同的形状。\n",
    "# 其次，对生成的数组执行按元素操作,在大多数情况下，我们将沿着数组中长度为1的轴进行广播\n",
    "a = torch.arange(3).reshape((3, 1))\n",
    "b = torch.arange(2).reshape((1, 2))\n",
    "print(a)\n",
    "print(b)\n",
    "# 由于a和b分别是3*1和1*2矩阵，如果让它们相加，它们的形状不匹配。 我们将两个矩阵广播为一个更大的3*2矩阵，\n",
    "# 如下所示：矩阵a将复制列， 矩阵b将复制行，然后再按元素相加\n",
    "a + b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 9, 10, 11]),\n",
       " tensor([[3, 4, 5],\n",
       "         [6, 7, 8]]))"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(12).reshape((-1, 3))\n",
    "x[-1], x[1:3]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0,  1,  2],\n",
      "        [ 3,  4,  5],\n",
      "        [ 6,  7,  8],\n",
      "        [ 9, 10, 11]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1, 10],\n",
       "        [ 3,  4,  5],\n",
       "        [ 6,  7,  8],\n",
       "        [ 9, 10, 11]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(x)\n",
    "x[0, 2] = 10\n",
    "x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[12, 12, 12],\n",
       "        [12, 12, 12],\n",
       "        [ 6,  7,  8],\n",
       "        [ 9, 10, 11]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果我们想为多个元素赋值相同的值，我们只需要索引所有元素，然后为它们赋值。\n",
    "# 例如，[0:2, :]访问第1行和第2行，其中“:”代表沿轴1（列）的所有元素\n",
    "x[0:2, :] = 12\n",
    "x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 运行一些操作可能会导致为新结果分配内存。 例如，如果我们用Y = X + Y，我们将取消引用Y指向的张量，\n",
    "# 而是指向新分配的内存处的张量\n",
    "x = torch.arange(3).reshape((3, 1))\n",
    "y = torch.arange(2).reshape((1, 2))\n",
    "before = id(y)\n",
    "y = x + y\n",
    "id(y) == before\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "id(z): 4925609760\n",
      "id(z): 4925609760\n"
     ]
    }
   ],
   "source": [
    "# 我们可以使用切片表示法将操作的结果分配给先前分配的数组\n",
    "# 首先创建一个新的矩阵Z，其形状与另一个Y相同， 使用zeros_like来分配一个全0的块\n",
    "z = torch.zeros_like(y)\n",
    "print(f'id(z): {id(z)}')\n",
    "z[:] = x + y\n",
    "print(f'id(z): {id(z)}')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果在后续计算中没有重复使用X， 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销\n",
    "x = torch.arange(3).reshape((3, 1))\n",
    "y = torch.arange(3).reshape((3, 1))\n",
    "before = id(x)\n",
    "x += y\n",
    "id(x) == before\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, torch.Tensor)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将深度学习框架定义的张量转换为NumPy张量（ndarray）很容易，反之也同样容易。\n",
    "# torch张量和numpy数组将共享它们的底层内存，就地操作更改一个张量也会同时更改另一个张量\n",
    "a = x.numpy()\n",
    "b = torch.tensor(a)\n",
    "type(a), type(b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([2.]), 2.0, 2.0, 2)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 要将大小为1的张量转换为Python标量，我们可以调用item函数或Python的内置函数\n",
    "a = torch.tensor([2.0])\n",
    "a, a.item(), float(a), int(a)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.13 ('d2l')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "6bdcd3dff61cfecb093f68bfbd67338d4a9739a04d65268bf3b66287b86a0a9e"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
